/**
 * Copyright (c) 2018, wuxie All rights reserved.
 * qq:16349023,mail:16349023@qq.com
 * 未经许可禁止任何人通过任何渠道使用、修改源代码.
 * 项目名称 : wxcloud
 *
 * @version V1.0
 */
package cn.xo68.boot.web.web;

import cn.xo68.boot.web.annotation.JsonWrapperIgnore;
import cn.xo68.core.entity.JsonResponsEntity;
import org.springframework.core.MethodParameter;
import org.springframework.http.*;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import javax.servlet.http.HttpServletResponse;


/**
 *  控制器方法返回值json封装处理者
 * @author wuxie
 * @date 2018/8/16 21:14
 *
 */
public class JsonWrapperMethodReturnValueHandler implements HandlerMethodReturnValueHandler {

    private final RequestResponseBodyMethodProcessor target;

    public JsonWrapperMethodReturnValueHandler(RequestResponseBodyMethodProcessor target) {
        this.target = target;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        if(HttpEntity.class.isAssignableFrom(returnType.getParameterType()) || Object.class.equals(returnType.getParameterType())){
            return false;
        }
        JsonWrapperIgnore jsonWrapperIgnore = returnType.getMethodAnnotation(JsonWrapperIgnore.class);
        if(jsonWrapperIgnore!=null){
            return false;
        }
        ResponseBody responseBody=returnType.getMethodAnnotation(ResponseBody.class);
        RestController restController= returnType.getContainingClass().getAnnotation(RestController.class);
        if(responseBody!=null || restController!=null){
            return true;
        }

        return false;
    }

    @Override
    public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        mavContainer.setRequestHandled(true);
        HttpServletResponse httpServletResponse=webRequest.getNativeResponse(HttpServletResponse.class);
        JsonResponsEntity<Object> jsonResponseEntity = JsonResponsEntity.ok().build(returnValue);
        target.handleReturnValue(jsonResponseEntity,returnType,mavContainer,webRequest);
    }
}
